package com.yiyuwanglu.basecore.util;

import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.bson.types.ObjectId;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBCursor;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import com.yiyuwanglu.basecore.vo.QueryMongoVo;
  
  
public final class MongoDBUtil {  
  
    private static final String HOST = "121.40.238.29";  
  
    private static final String dbName = "test";  
  
    private static Mongo mongo;  
  
    private static DB db;  
    public static void main(String[] args) {
    	DBCursor find = MongoDBUtil.getCollection("statistics").find();
    	Set<String> set=new HashSet<String>();
    	while(find.hasNext()){
    		DBObject next = find.next();
    		System.out.println(next.toString());
    		set.add(next.get("userId")+"");
    	}
    	
    	for (String string : set) {
			System.out.println(string);
		}
    }
    
    
	/**
	 * 根据 QueryMongoVo 赋值 Mongo Query
	 * 
	 * @param queryVo
	 * @return Query
	 */
	private Query getQuery(QueryMongoVo queryVo) {

		Query query = new Query();
		Criteria criteria = new Criteria();
		if (StringUtils.isNotBlank(queryVo.getIp())) {
			criteria.and("ip").is(queryVo.getIp());
		}
		query.addCriteria(criteria);
		return query;

	}
	/**
	 * 根据 QueryMongoVo 
	 * match 查询条件 
	 * group 分组字段
	 * sort  排序字段
	 * @param queryVo
	 * @return aggregation
	 */
	private static Aggregation getAggregateCreateDate(QueryMongoVo queryVo){
		
		  AggregationOperation match = Aggregation.match(getCriteria(queryVo));
		  
		 AggregationOperation group = Aggregation.group("userId").first("userId").as("userId").count().as("countUserId");
		  
		  Direction direction = Direction.DESC;
		  
		  AggregationOperation sort = Aggregation.sort(new Sort(direction,"createDate"));
		  
		  Aggregation aggregation =  Aggregation.newAggregation(match,group,sort);
		
		  return aggregation;
		
	}
	/**
	 * 根据 QueryMongoVo 赋值 Mongo getCriteria
	 * 
	 * @param queryVo
	 * @return Criteria
	 */
	private static Criteria getCriteria(QueryMongoVo queryVo) {

		Criteria criteria = new Criteria();
		
		if (StringUtils.isNotBlank(queryVo.getIp())) {
			criteria.and("ip").is(queryVo.getIp());
		}
		
		if (StringUtils.isNotBlank(queryVo.getLoginName())) {
			criteria.and("loginName").is(queryVo.getLoginName());
		}
		return criteria;

	}
    
    
    static {  
        try {  
            mongo = new Mongo(HOST);  
            db = mongo.getDB(dbName);  
           // boolean auth= db.authenticate("sfa","sfa123".toCharArray());  
            //System.out.println(auth);
        } catch (UnknownHostException e) {  
            e.printStackTrace();  
        } catch (MongoException e) {  
            e.printStackTrace();  
        }  
    }  
  
    private MongoDBUtil() {  
    }  
  
    /** 
     * 添加操作 
     * <br>------------------------------<br> 
     * @param map 
     * @param collectionName 
     */  
    public static void add(Map<String, Object> map, String collectionName) {  
        DBObject dbObject = new BasicDBObject(map);  
        getCollection(collectionName).insert(dbObject);  
    }  
      
    /** 
     * 添加操作 
     * <br>------------------------------<br> 
     * @param list 
     * @param collectionName 
     */  
    public static void add(List<Map<String, Object>> list, String collectionName) {  
        for (Map<String, Object> map : list) {  
            add(map, collectionName);  
        }  
    }  
      
    /** 
     * 删除操作 
     * <br>------------------------------<br> 
     * @param map 
     * @param collectionName 
     */  
    public static void delete(Map<String, Object> map, String collectionName) {  
        DBObject dbObject = new BasicDBObject(map);  
        getCollection(collectionName).remove(dbObject);  
    }  
      
    /** 
     * 删除操作,根据主键 
     * <br>------------------------------<br> 
     * @param id             
     * @param collectionName 
     */  
    public static void delete(String id, String collectionName) {  
        Map<String, Object> map = new HashMap<String, Object>();  
        map.put("_id", new ObjectId(id));  
        delete(map, collectionName);  
    }  
      
    /** 
     * 删除全部 
     * <br>------------------------------<br> 
     * @param collectionName 
     */  
    public static void deleteAll(String collectionName) {  
        getCollection(collectionName).drop();  
    }  
      
    /** 
     * 修改操作</br> 
     * 会用一个新文档替换现有文档,文档key结构会发生改变</br> 
     * 比如原文档{"_id":"123","name":"zhangsan","age":12}当根据_id修改age  
     * value为{"age":12}新建的文档name值会没有,结构发生了改变 
     * <br>------------------------------<br> 
     * @param whereMap       
     * @param valueMap       
     * @param collectionName 
     */  
    public static void update(Map<String, Object> whereMap, Map<String, Object> valueMap, String collectionName) {  
        executeUpdate(collectionName, whereMap, valueMap, new UpdateCallback(){  
            public DBObject doCallback(DBObject valueDBObject) {  
                return valueDBObject;  
            }  
        });  
    }   
      
    /** 
     * 修改操作,使用$set修改器</br> 
     * 用来指定一个键值,如果键不存在,则自动创建,会更新原来文档, 不会生成新的, 结构不会发生改变 
     * <br>------------------------------<br> 
     * @param whereMap       
     * @param valueMap       
     * @param collectionName 
     */  
    public static void updateSet(Map<String, Object> whereMap, Map<String, Object> valueMap, String collectionName) {  
        executeUpdate(collectionName, whereMap, valueMap, new UpdateCallback(){  
            public DBObject doCallback(DBObject valueDBObject) {  
                return new BasicDBObject("$set", valueDBObject);  
            }  
        });  
    }   
      
    /** 
     * 修改操作,使用$inc修改器</br> 
     * 修改器键的值必须为数字</br> 
     * 如果键存在增加或减少键的值, 如果不存在创建键 
     * <br>------------------------------<br> 
     * @param whereMap       
     * @param valueMap       
     * @param collectionName 
     */  
    public static void updateInc(Map<String, Object> whereMap, Map<String, Integer> valueMap, String collectionName) {  
        executeUpdate(collectionName, whereMap, valueMap, new UpdateCallback(){  
            public DBObject doCallback(DBObject valueDBObject) {  
                return new BasicDBObject("$inc", valueDBObject);  
            }  
        });  
    }   
      
    /** 
     * 修改 
     * <br>------------------------------<br> 
     * @param collectionName 
     * @param whereMap 
     * @param valueMap 
     * @param updateCallback 
     */  
    private static void executeUpdate(String collectionName, Map whereMap, Map valueMap, UpdateCallback updateCallback) {  
        DBObject whereDBObject = new BasicDBObject(whereMap);  
        DBObject valueDBObject = new BasicDBObject(valueMap);  
        valueDBObject = updateCallback.doCallback(valueDBObject);  
        getCollection(collectionName).update(whereDBObject, valueDBObject);  
    }  
      
    interface UpdateCallback {  
          
        DBObject doCallback(DBObject valueDBObject);  
    }  
      
    /** 
     * 获取集合(表) 
     * <br>------------------------------<br> 
     * @param collectionName 
     * @return 
     */  
    public static DBCollection getCollection(String collectionName) {  
        return db.getCollection(collectionName);  
    }  
    
}  